package cn.ac.iie.ulss.dataredistribution.commons;

import cn.ac.iie.ulss.dataredistribution.config.Configuration;
import cn.ac.iie.ulss.dataredistribution.config.ConfigurationException;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

/**
 *
 * @author: evan
 * @date: 2014-10-13
 */
public class RuntimeEnv {

    public static final String ZK_CLUSTER = "zkCluster";
    public static final String NODENAME = "nodeName";
    public static final String URL_END = "urlEnd";
    public static final String ACCEPT_SIZE = "acceptSize";
    public static final String SEND_SIZE = "sendSize";
    public static final String FILE_MAXSIZE = "fileMaxSize";
    public static final String MQ_NAME_SERVER = "mqNameServer";
    public static final String MQ_TOPIC_NAME = "mqTopicName";
    public static final String MQ_FETCH_RUNNER_SIZE = "mqFetchRunnerSize";
    public static final String METASTORE_CLIENT = "metaStoreClient";
    public static final String METASTORE_CLIENT_POOL_SIZE = "metaStoreClientPoolSize";
    public static final String METASTORE_ZK_CLUSTER = "metaStoreZkCluster";
    public static final String DATA_DIR = "dataDir";
    public static final String DATA_POOL_COUNT = "dataPoolCount";
    public static final String TRANSMIT_THREAD_SIZE = "transmitThreadSize";
    public static final String DATASENDER_THREAD_SIZE = "dataSenderThreadSize";
    public static final String DATASENDER_LIMITTIME = "dataSenderLimitTime";
    public static final String SEND_TIMEOUT = "sendTimeout";
    public static final String USELESS_FILE = "uselessFile";
    private static Map<String, Object> dynamicParams = new HashMap<String, Object>();
    private static Configuration conf = null;
    static Logger logger = null;

    static {
        PropertyConfigurator.configure("log4j.properties");
        logger = Logger.getLogger(RuntimeEnv.class.getName());
    }

    /**
     *
     * initialize the RuntimeEnv from the configuration file
     */
    public static boolean initialize(Configuration pConf) throws ConfigurationException {
        if (pConf == null) {
            logger.error("configuration object is null");
            return false;
        }

        conf = pConf;

        String zkCluster = conf.getString(ZK_CLUSTER, "");
        if (zkCluster.isEmpty()) {
            logger.error("parameter zkCluster does not exist or is not defined");
            return false;
        }
        logger.info("get zkCluster " + zkCluster);
        dynamicParams.put(ZK_CLUSTER, zkCluster);

        String nodename = conf.getString(NODENAME, "");
        if (nodename.isEmpty()) {
            logger.error("parameter nodename does not exist or is not defined");
            return false;
        }
        logger.info("get nodename " + nodename);
        dynamicParams.put(NODENAME, nodename);

        String urlend = conf.getString(URL_END, "");
        if (urlend.isEmpty()) {
            logger.error("parameter urlend does not exist or is not defined");
            return false;
        }
        logger.info("get urlend " + urlend);
        dynamicParams.put(URL_END, urlend);

        int acceptSize = conf.getInt(ACCEPT_SIZE, 0);
        if (acceptSize < 0) {
            logger.error("parameter acceptSize is a wrong number");
            return false;
        }
        logger.info("get acceptSize " + acceptSize);
        dynamicParams.put(ACCEPT_SIZE, acceptSize);
        
        int sendSize = conf.getInt(SEND_SIZE, 0);
        if (sendSize < 0) {
            logger.error("parameter sendSize is a wrong number");
            return false;
        }
        logger.info("get sendSize " + sendSize);
        dynamicParams.put(SEND_SIZE, sendSize);
        
        int fileMaxsize = conf.getInt(FILE_MAXSIZE, 0);
        if (fileMaxsize < 0) {
            logger.error("parameter fileMaxsize is a wrong number");
            return false;
        }
        logger.info("get fileMaxsize " + fileMaxsize);
        dynamicParams.put(FILE_MAXSIZE, fileMaxsize);
        
        String mqnameserver = conf.getString(MQ_NAME_SERVER, "");
        if (mqnameserver.isEmpty()) {
            logger.error("parameter mqnameserver does not exist or is not defined");
            return false;
        }
        logger.info("get mqnameserver " + mqnameserver);
        dynamicParams.put(MQ_NAME_SERVER, mqnameserver);

        String mqTopicName = conf.getString(MQ_TOPIC_NAME, "");
        if (mqTopicName.isEmpty()) {
            logger.error("parameter mqTopicName does not exist or is not defined");
            return false;
        }
        logger.info("get mqTopicName " + mqTopicName);
        dynamicParams.put(MQ_TOPIC_NAME, mqTopicName);
        
        int mqfetchrunnersize = conf.getInt(MQ_FETCH_RUNNER_SIZE, 12);
        if (mqfetchrunnersize < 0) {
            logger.error("parameter mqfetchrunnersize is a wrong number");
            return false;
        }
        logger.info("get mqfetchrunnersize " + mqfetchrunnersize);
        dynamicParams.put(MQ_FETCH_RUNNER_SIZE, mqfetchrunnersize);

        String metaStoreClient = conf.getString(METASTORE_CLIENT, "");
        if (metaStoreClient.isEmpty()) {
            logger.error("parameter metaStoreClient does not exist or is not defined");
            return false;
        }
        logger.info("get metaStoreClient " + metaStoreClient);
        dynamicParams.put(METASTORE_CLIENT, metaStoreClient);

        int metaStoreClientPoolSize = conf.getInt(METASTORE_CLIENT_POOL_SIZE, 20);
        if (metaStoreClientPoolSize <= 0) {
            logger.error("parameter metaStoreClientPoolSize is a wrong number");
            return false;
        }
        logger.info("get metaStoreClientPoolSize " + metaStoreClientPoolSize);
        dynamicParams.put(METASTORE_CLIENT_POOL_SIZE, metaStoreClientPoolSize);

        String metaStoreZkCluster = conf.getString(METASTORE_ZK_CLUSTER, "");
        if (metaStoreZkCluster.isEmpty()) {
            logger.error("parameter metaStoreZkCluster does not exist or is not defined");
            return false;
        }
        logger.info("get metaStoreZkCluster " + metaStoreZkCluster);
        dynamicParams.put(METASTORE_ZK_CLUSTER, metaStoreZkCluster);

        String dataDir = conf.getString(DATA_DIR, "");
        if (dataDir.isEmpty()) {
            logger.error("parameter dataDir does not exist or is not defined");
            return false;
        }
        logger.info("get dataDir " + dataDir);
        dynamicParams.put(DATA_DIR, dataDir);

        int datapoolcount = conf.getInt(DATA_POOL_COUNT, 5);
        if (datapoolcount < 0) {
            logger.error("parameter datapoolcount is a wrong number");
            return false;
        }
        logger.info("get datapoolcount " + datapoolcount);
        dynamicParams.put(DATA_POOL_COUNT, datapoolcount);

        int transmitThreadSize = conf.getInt(TRANSMIT_THREAD_SIZE, 5);
        if (transmitThreadSize <= 0) {
            logger.error("parameter transmitThreadSize is a wrong number");
            return false;
        }
        logger.info("get transmitThreadSize " + transmitThreadSize);
        dynamicParams.put(TRANSMIT_THREAD_SIZE, transmitThreadSize);

        int datasenderThreadSize = conf.getInt(DATASENDER_THREAD_SIZE, 2);
        if (datasenderThreadSize <= 0) {
            logger.error("parameter datasenderThreadSize is a wrong number");
            return false;
        }
        logger.info("get datasenderThreadSize " + datasenderThreadSize);
        dynamicParams.put(DATASENDER_THREAD_SIZE, datasenderThreadSize);

        int datasenderLimitTime = conf.getInt(DATASENDER_LIMITTIME, 1000);
        if (datasenderLimitTime <= 0) {
            logger.error("parameter datasenderLimitTime is a wrong number");
            return false;
        }
        logger.info("get datasenderLimitTime " + datasenderLimitTime);
        dynamicParams.put(DATASENDER_LIMITTIME, datasenderLimitTime);

        int sendtimeout = conf.getInt(SEND_TIMEOUT, 60);
        if (sendtimeout <= 0) {
            logger.error("parameter sendtimeout is a wrong number");
            return false;
        }
        logger.info("get sendtimeout " + sendtimeout);
        dynamicParams.put(SEND_TIMEOUT, sendtimeout);

        int uselessfile = conf.getInt(USELESS_FILE, 1);
        if (uselessfile < 0) {
            logger.error("parameter uselessfile is a wrong number");
            return false;
        }
        logger.info("get uselessfile " + uselessfile);
        dynamicParams.put(USELESS_FILE, uselessfile);

        return true;
    }

    public static void dumpEnvironment() {
        conf.dumpConfiguration();
    }

    /**
     *
     * add the param to the RuntimeEnv
     */
    public synchronized static void addParam(String pParamName, Object pValue) {
        dynamicParams.put(pParamName, pValue);
    }

    /**
     *
     * get the param to the RuntimeEnv
     */
    public static Object getParam(String pParamName) {
        return dynamicParams.get(pParamName);
    }
}
